<template>
  <div class="form-item" :class="{ 'form-item--invalid': fieldState.invalid }">
    <!-- 标签 -->
    <label class="form-item__label" :for="field">{{ label }}</label>
    <!-- 输入框 -->
    <input
      class="form-item__input"
      :id="field"
      :type="type"
      :placeholder="placeholder"
      @input="handleInput"
      @blur="handleBlur"
      ref="inputRef"
    />
    <!-- 错误提示 -->
    <div class="form-item__error" v-if="fieldState.invalid">
      <span v-for="(err, idx) in fieldState.errors" :key="idx">{{ err }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useValidationInject } from '@/utils/injection';
import type { ValidatorRule } from '@/types/validation';

// 子组件接收的 props
const props = defineProps<{
  // 表单项唯一标识（与父表单对应）
  field: string;
  // 标签文本
  label: string;
  // 输入框类型（text/password/number 等）
  type?: string;
  // 占位符
  placeholder?: string;
  // 校验规则
  rules: ValidatorRule[];
  // 关联的父表单 key（确保注入正确上下文）
  formKey: string;
}>();

// 输入框 DOM 引用（用于传递给校验上下文）
const inputRef = ref<HTMLInputElement | null>(null);

// 注入父表单的校验上下文
const validationContext = useValidationInject(props.formKey);

// 当前表单项的状态（从上下文获取）
const fieldState = ref(
  validationContext.fields[props.field] || {
    field: props.field,
    invalid: false,
    errors: []
  }
);

// 挂载时：将当前表单项添加到父表单的校验上下文
onMounted(() => {
  if (inputRef.value) {
    // 注册表单项到父表单
    validationContext.addFieldValidator(props.field, props.rules, inputRef.value);
    // 同步表单项状态（从上下文更新）
    fieldState.value = validationContext.fields[props.field];
  }
});

// 输入时：实时校验（可选，根据需求调整）
const handleInput = (e: Event) => {
  const value = (e.target as HTMLInputElement).value;
  // 调用父上下文的校验方法
  const newState = validationContext.validateField(props.field, value);
  fieldState.value = newState;
};

// 失焦时：再次校验（确保最终输入符合规则）
const handleBlur = () => {
  if (inputRef.value) {
    const value = inputRef.value.value;
    const newState = validationContext.validateField(props.field, value);
    fieldState.value = newState;
  }
};
</script>

<style scoped lang="scss">
@import '@/styles/form.scss';

.form-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
  transition: all 0.3s;

  &--invalid {
    .form-item__input {
      border-color: var(--error-color);
    }
  }

  &__label {
    font-size: 14px;
    color: var(--text-color);
    font-weight: 500;
  }

  &__input {
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    font-size: 14px;
    transition: border-color 0.3s;

    &:focus {
      outline: none;
      border-color: var(--primary-color);
      box-shadow: 0 0 0 2px rgba(48, 121, 243, 0.2);
    }
  }

  &__error {
    font-size: 12px;
    color: var(--error-color);
    line-height: 1.4;

    span {
      display: block;
      margin-top: 4px;
    }
  }
}
</style>
